﻿#pragma once

// clang-format off
#define FMT_HEADER_ONLY
#define SPDLOG_HEADER_ONLY
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LOGGER_INFO
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"
// clang-format on

namespace libdaq {

#ifdef _WIN32
#define DAQ_LIBRARY_EXPORT __declspec(dllexport)
#else
#define DAQ_LIBRARY_EXPORT __attribute__((visibility("default")))
#endif


class DAQ_LIBRARY_EXPORT DAQLibraryLogger {
  public:
    static spdlog::logger* GetLogger();

  private:
    DAQLibraryLogger();
    inline static spdlog::logger* base_logger_ = nullptr;
};

#define DAQ_LIBRARY_LOGGER_INFO(...)                     	\
{                                                         	\
  auto get_logger = DAQLibraryLogger::GetLogger(); 		\
  SPDLOG_LOGGER_INFO(get_logger, __VA_ARGS__);            	\
}

#define DAQ_LIBRARY_LOGGER_DEBUG(...)                     \
{                                                         	\
  auto get_logger = DAQLibraryLogger::GetLogger(); 		\
  SPDLOG_LOGGER_DEBUG(get_logger, __VA_ARGS__);           	\
}

#define DAQ_LIBRARY_LOGGER_WARN(...)                      \
{                                                         	\
  auto get_logger = DAQLibraryLogger::GetLogger(); 		\
  SPDLOG_LOGGER_WARN(get_logger, __VA_ARGS__);            	\
}

#define DAQ_LIBRARY_LOGGER_ERROR(...)                     \
{                                                         	\
  auto get_logger = DAQLibraryLogger::GetLogger(); 		\
  SPDLOG_LOGGER_ERROR(get_logger, __VA_ARGS__);           	\
}

#define DAQ_LIBRARY_LOGGER_CRITICAL(...)               	\
{                                                         	\
  auto get_logger = DAQLibraryLogger::GetLogger(); 		\
  SPDLOG_LOGGER_CRITICAL(get_logger, __VA_ARGS__);        	\
}

#ifdef NDEBUG
#define DAQ_LIBRARY_LOGGER_ASSERT(flag, ...) 		\
{                                             		\
  if(!(flag)) {                                   	\
    DAQ_LIBRARY_LOGGER_CRITICAL(__VA_ARGS__)   	\
	  exit(-1);										\
  }                                            		\
}
#else
#define DAQ_LIBRARY_LOGGER_ASSERT(flag, ...) 		\
{                                             		\
  if(!(flag)) {                                   	\
    DAQ_LIBRARY_LOGGER_CRITICAL(__VA_ARGS__)   	\
  }                                            		\
  assert(flag);                                  	\
}
#endif
} // namespace lockzhiner
